#include <stdio.h>
#include <modbus-rtu.h>
#include <modbus-tcp.h>
#include <modbus.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/shm.h>
#include <errno.h>

uint16_t dest[10] = {};
modbus_t *ctx = NULL;
char buf[10] = "";
struct msgbuf
{
    long mtype;
    int num1;
    int num2;
};
void *handler_thread(void *arg)
{

    while (1)
    {
        int c = modbus_read_registers(ctx, 0, 4, dest);
        if (c < 0)
        {
            perror("registers err");
            return NULL;
        }
        key_t key2;
        int shmid;
        key2 = ftok("shm.c", 'c');
        if (key2 < 0)
        {
            perror("ftok err");
            return NULL;
        }
        shmid = shmget(key2, 128, IPC_CREAT | IPC_EXCL | 0777);
        if (shmid <= 0)
        {
            if (errno == EEXIST)
            {
                shmid = shmget(key2, 128, 0777);
            }
            else
            {
                perror("shemget err");
                return NULL;
            }
        }
        char *p = (char *)shmat(shmid, NULL, 0);
        if (p == (char *)-1)
        {
            perror("shmat err");
            return NULL;
        }
        sprintf(p, "%d %d %d %d\n", dest[0], dest[1], dest[2], dest[3]);
        //printf(p, "%d %d %d %d\n", dest[0], dest[1], dest[2], dest[3]);
        sleep(3);
    }
}
void *handler_ctl(void *arg)
{
    key_t key;
    key = ftok("msg.c", 'a');
    if (key < 0)
    {
        perror("ftok err");
    }
    int msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
    if (msgid < 0)
    {
        if (errno == EEXIST)
            msgid = msgget(key, 0666);
        else
        {
            perror("msgget err");
        }
    }
    int num1, num2;
    struct msgbuf msg;
    while (1)
    {
        msgrcv(msgid, &msg, sizeof(struct msgbuf) - sizeof(long), 1, 0);
        num1 = msg.num1;
        num2 = msg.num2;
        printf("%d %d\n", num1, num2);
        if (num1 == 0 && num2 == 1)
        {
            modbus_write_bit(ctx, 0, 1); // LED灯开
            printf("LED灯开\n");
        }
        else if (num1 == 0 && num2 == 0)
        {
            modbus_write_bit(ctx, 0, 0); // LED灯关
            printf("LED灯关\n");
        }
        else if (num1 == 1 && num2 == 1)
        {
            modbus_write_bit(ctx, 1, 1); // 蜂鸣器开
            printf("蜂鸣器开\n");
        }
        else if (num1 == 1 && num2 == 0)
        {
            modbus_write_bit(ctx, 1, 0); // 蜂鸣器关
            printf("蜂鸣器关\n");
        }
    }
}
int main(int argc, char const *argv[])
{
    ctx = modbus_new_tcp(argv[1], atoi(argv[2]));
    if (ctx == NULL)
    {
        perror("modbus_new_tcp err");
        return -1;
    }
    int a = modbus_set_slave(ctx, 1);
    if (a < 0)
    {
        perror("slave err");
        return -1;
    }
    int b = modbus_connect(ctx);
    if (b < 0)
    {
        perror("connect err");
        return -1;
    }
    pthread_t tid1;
    if (pthread_create(&tid1, NULL, handler_thread, NULL) != 0)
    {
        perror("pthread create err1");
        return -1;
    }
    pthread_t tid2;
    if (pthread_create(&tid2, NULL, handler_ctl, NULL) != 0)
    {
        perror("pthread create err2");
        return -1;
    }
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    modbus_close(ctx);
    modbus_free(ctx);
    return 0;
}
